/*
 * @Author: vasebox 994279430@qq.com
 * @Date: 2025-04-25 17:16:56
 * @LastEditors: vasebox 994279430@qq.com
 * @LastEditTime: 2025-04-25 17:21:29
 * @FilePath: \micro-app-main\src\utils\http-yield.ts
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
// 定义一个函数，用于获取流式数据
export async function fetchStreamedData(url: string): Promise<ReadableStream<Uint8Array>> {
    // 使用 fetch 请求指定的 URL
    const response = await fetch(url);

    // 如果响应状态码不是 2xx，抛出错误
    if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
    }

    // 检查响应是否支持 ReadableStream
    if (!response.body) {
        throw new Error('ReadableStream not supported in this environment.');
    }

    // 返回响应的 body（流）
    return response.body;
}

// 定义一个异步生成器函数，用于解析流式 JSON 数据
export async function* streamJsonData<T>(url: string): AsyncGenerator<T> {
    // 获取流式数据
    const stream = await fetchStreamedData(url);
    // 获取流的读取器
    const reader = stream.getReader();
    // 创建一个文本解码器，用于将 Uint8Array 解码为字符串
    const decoder = new TextDecoder('utf-8');
    let buffer = ''; // 用于存储未处理的缓冲区数据

    try {
        while (true) {
            // 从流中读取数据
            const { done, value } = await reader.read();
            if (done) break; // 如果流结束，退出循环

            // 将读取到的数据解码为字符串并追加到缓冲区
            buffer += decoder.decode(value, { stream: true });

            // 查找缓冲区中换行符的位置
            let boundary = buffer.indexOf('\n');
            while (boundary !== -1) {
                // 提取一行数据
                const chunk = buffer.slice(0, boundary).trim();
                // 更新缓冲区，移除已处理的数据
                buffer = buffer.slice(boundary + 1);

                // 如果行数据不为空，解析为 JSON 并产出
                if (chunk) {
                    yield JSON.parse(chunk) as T;
                }

                // 查找下一行的换行符
                boundary = buffer.indexOf('\n');
            }
        }

        // 如果缓冲区中还有剩余数据，解析并产出
        if (buffer.trim()) {
            yield JSON.parse(buffer.trim()) as T;
        }
    } finally {
        // 释放读取器的锁
        reader.releaseLock();
    }
}